﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Quba.Business.Services.Abstract.Question;
using Quba.Business.Services.Abstract.Tag;
using Quba.Business.Services.Concrete.Question;
using Quba.Business.Services.Concrete.Tag;
using Quba.Entities.Database.General;
using Quba.Entities.Database.Question;
using Quba.Entities.Database.Tag;

namespace Quba.Tests.Business
{
    [TestClass]
    public class QuestionBusinessTests
    {
        private readonly IQuestionBusiness _questionBusiness;
        private readonly IQuestionPaperBusiness _questionPaperBusiness;
        private readonly IQuestionTypeBusiness _questionTypeBusiness;
        private readonly IAnswerPaperBusiness _answerPaperBusiness;
        private readonly ITagBusiness _tagBusiness;


        public QuestionBusinessTests()
        {
            _questionBusiness = new QuestionBusiness();
            _questionPaperBusiness = new QuestionBusiness();
            _questionTypeBusiness = new QuestionBusiness();
            _answerPaperBusiness = new QuestionBusiness();
            _tagBusiness = new TagBusiness();
        }

        [TestMethod]
        public void CanAddaQuestionType()
        {
            var questionType = new QuestionType
                                   {
                                       Name = "NoOptions",
                                       CreatedBy = "AirWatch-HR",
                                       CreatedOn = DateTime.Now,
                                       ModifiedBy = "AirWatch-HR",
                                       ModifiedOn = DateTime.Now
                                   };
            var type1 = _questionTypeBusiness.AddQuestionType(questionType);

            Assert.IsNotNull(type1);
            Assert.IsNotNull(type1.Id);

            var type = new QuestionType
                           {
                               Name = "MultipleOptions",
                               CreatedBy = "AirWatch-HR",
                               CreatedOn = DateTime.Now,
                               ModifiedBy = "AirWatch-HR",
                               ModifiedOn = DateTime.Now
                           };

            var type2 = _questionTypeBusiness.AddQuestionType(type);

            Assert.IsNotNull(type2);
            Assert.IsTrue(type2.Id > 0);

        }

        [TestMethod]
        public void CanAddaTag()
        {
            //Insert a tag
            var tag1 = new Tag
            {
                Name = "C#",
                Description = "C#",
                CreatedBy = "AirWatch-HR",
                CreatedOn = DateTime.Now,
                ModifiedBy = "AirWatch-HR",
                ModifiedOn = DateTime.Now
            };

            var tagId1 = _tagBusiness.AddTag(tag1).Id;
            Assert.IsTrue(tagId1 > 0);

            //Insert a tag
            var tag2 = new Tag
            {
                Name = "GK",
                Description = "General Knowledge",
                CreatedBy = "AirWatch-HR",
                CreatedOn = DateTime.Now,
                ModifiedBy = "AirWatch-HR",
                ModifiedOn = DateTime.Now
            };

            var tagId2 = _tagBusiness.AddTag(tag2).Id;
            Assert.IsTrue(tagId2 > 0);
        }

        [TestMethod]
        public void CanAddAQuestionToBank()
        {
            //Get the tag
            var tag = _tagBusiness.GetTagDetails(1);
            var type = _questionTypeBusiness.GetQuestionTypeDetails(2);

            var baseEntity = _AddQuestion(tag, type, "India's capital is", new List<string> { "New Delhi" , "Mumbai"});

            Assert.IsNotNull(baseEntity);
            Assert.IsTrue(baseEntity.Id > 0);
        }

        
        private Question _AddQuestion(Tag newTag, QuestionType type, string questionText, List<string> answerTexts)
        {
            var question = new Question
                           {
                               Text = questionText,
                               Tags = newTag.Name,
                               Status = true,
                               Type = type,
                               Options = new List<Option>
                                             {
                                                 new Option
                                                     {
                                                         Sequence = 0,
                                                         Text = answerTexts[0],
                                                         CreatedBy = "AirWatch-HR",
                                                         CreatedOn = DateTime.Now,
                                                         ModifiedBy = "AirWatch-HR",
                                                         ModifiedOn = DateTime.Now
                                                     },
                                                 new Option
                                                     {
                                                         Sequence = 1,
                                                         Text = answerTexts[1],
                                                         CreatedBy = "AirWatch-HR",
                                                         CreatedOn = DateTime.Now,
                                                         ModifiedBy = "AirWatch-HR",
                                                         ModifiedOn = DateTime.Now
                                                     }
                                             },
                               CorrectAnswerOptionId = 1,
                               CreatedBy = "AirWatch-HR",
                               CreatedOn = DateTime.Now,
                               ModifiedBy = "AirWatch-HR",
                               ModifiedOn = DateTime.Now
                           };
            var baseEntity = _questionBusiness.AddQuestionToBank(question);
            
            Assert.IsNotNull(baseEntity);
            Assert.IsTrue(baseEntity.Id > 0);

            var result = _questionBusiness.GetQuestionDetailsById(baseEntity.Id);

            Assert.IsNotNull(result);
            Assert.IsTrue(result.Id > 0);
            return result;
        }

        [TestMethod]
        public void CanAddAQuestionPaper()
        {
            var questions = new List<Question>();
            var tag = _tagBusiness.GetTagDetails(1);
            var type = _questionTypeBusiness.GetQuestionTypeDetails(2);

            questions.AddRange(new List<Question>
                                   {
                                       _AddQuestion(tag, type, "Karnataka's capital is", new List<string> { "Bangalore" , "Mysore"}),
                                       _AddQuestion(tag, type, "Orissa's capital is", new List<string> { "BBSR" , "Cuttack"})
                                   }); 

            var questionPaper = new QuestionPaper
                                    {
                                        Name = "GK",
                                        Status = true,
                                        Code = "",
                                        QuestionIds = "",
                                        Questions = questions
                                    };
            var result = _questionPaperBusiness.AddQuestionPaper(questionPaper);

            Assert.IsNotNull(questionPaper);
            Assert.IsTrue(questionPaper.Id > 0);
        }
    }
}